package com.lry.jvm.rtda.heap;

import com.lry.jvm.classfile.MemberInfo;
import lombok.Data;

//字段和方法
@Data
public class ClassMember {

    private int accessFlag;
    private String name;
    private String descriptor;
    private JClass jClass;

    public void copyMemberInfo(MemberInfo memberInfo) {
        this.accessFlag = memberInfo.getAccessFlags();
        this.name = memberInfo.name();
        this.descriptor = memberInfo.descriptor();
    }

    public boolean isVolatile() {
        return 0 != (getAccessFlag() & AccessFlags.ACC_VOLATILE);
    }

    public boolean IsTransient() {
        return 0 != (getAccessFlag() & AccessFlags.ACC_VOLATILE);
    }

    public boolean IsEnum() {
        return 0 != (getAccessFlag() & AccessFlags.ACC_VOLATILE);
    }

    public boolean isStatic() {
        return 0 != (getAccessFlag() & AccessFlags.ACC_STATIC);
    }

    public boolean isFinal() {
        return 0 != (getAccessFlag() & AccessFlags.ACC_FINAL);
    }

    public boolean isLongOrDouble() {
        return getDescriptor() == "J" || getDescriptor() == "D";
    }

    public boolean isPublic() {
        return 0 != (accessFlag & AccessFlags.ACC_PUBLIC);
    }

    public boolean isProtected() {
        return 0 != (accessFlag & AccessFlags.ACC_PROTECTED);
    }

    public boolean isPrivate() {
        return 0 != (accessFlag & AccessFlags.ACC_PRIVATE);
    }

    public boolean isAccessibleTo(JClass d) {
        if (isPublic()) {
            return true;
        }

        JClass c = this.jClass;
        if (isProtected()) {
            return (d == c || d.isSubClassOf(c)
                    || c.getPackageName() == d.getPackageName());
        }

        if (!isPrivate()) {
            return c.getPackageName() == d.getPackageName();
        }
        return d == c;
    }

    public boolean isNative() {
        return 0 != (accessFlag & AccessFlags.ACC_NATIVE);
    }
}